<!DOCTYPE html>



  


<html class="theme-next muse use-motion" lang="zh-CN">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/hexo/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/hexo/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/hexo/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/hexo/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/hexo/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/hexo/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/hexo/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="开发笔记,">










<meta name="description" content="最近项目中涉及到一个大批量生成且插入数据的操作，大到啥程度呢，可能一次性插入超过50000条记录（好像也不是很大），那在系统中涉及到较大规模的数据读写操作时，为了同时兼顾效率和用户体验，肯定需要一些特殊的处理方式，说一下我的例子吧，可能不是最优的解决方案，但自我感觉良好我遇到的需求是这样，要生成一批保证不唯一随机码（8位字母数字），然后将随机码以及其他数据构造模型列表，一并插入到数据库中；需求很简">
<meta name="keywords" content="开发笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="一次大数据量操作的方法实例">
<meta property="og:url" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/index.html">
<meta property="og:site_name" content="Tony&#39;s blog">
<meta property="og:description" content="最近项目中涉及到一个大批量生成且插入数据的操作，大到啥程度呢，可能一次性插入超过50000条记录（好像也不是很大），那在系统中涉及到较大规模的数据读写操作时，为了同时兼顾效率和用户体验，肯定需要一些特殊的处理方式，说一下我的例子吧，可能不是最优的解决方案，但自我感觉良好我遇到的需求是这样，要生成一批保证不唯一随机码（8位字母数字），然后将随机码以及其他数据构造模型列表，一并插入到数据库中；需求很简">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/1.png">
<meta property="og:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/2.png">
<meta property="og:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/3.png">
<meta property="og:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/%E5%BD%A9%E8%9B%8B1.png">
<meta property="og:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/%E5%BD%A9%E8%9B%8B2.png">
<meta property="og:updated_time" content="2018-12-27T04:10:22.970Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="一次大数据量操作的方法实例">
<meta name="twitter:description" content="最近项目中涉及到一个大批量生成且插入数据的操作，大到啥程度呢，可能一次性插入超过50000条记录（好像也不是很大），那在系统中涉及到较大规模的数据读写操作时，为了同时兼顾效率和用户体验，肯定需要一些特殊的处理方式，说一下我的例子吧，可能不是最优的解决方案，但自我感觉良好我遇到的需求是这样，要生成一批保证不唯一随机码（8位字母数字），然后将随机码以及其他数据构造模型列表，一并插入到数据库中；需求很简">
<meta name="twitter:image" content="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/1.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/hexo/',
    scheme: 'Muse',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Tony'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://tony_df.coding.net/2018/12/26/一次大数据量操作的方法实例/">





  <title>一次大数据量操作的方法实例 | Tony's blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/hexo/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Tony's blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">学着码代码,学着码人生;</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/hexo/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/hexo/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Tags
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/hexo/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br>
            
            Archives
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://tony_df.coding.net/hexo/2018/12/26/一次大数据量操作的方法实例/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Tony">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/hexo/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Tony's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">一次大数据量操作的方法实例</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2018-12-26T15:43:11+08:00">
                2018-12-26
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>最近项目中涉及到一个大批量生成且插入数据的操作，大到啥程度呢，可能一次性插入超过50000条记录（好像也不是很大<del>），那在系统中涉及到较大规模的数据读写操作时，为了同时兼顾效率和用户体验，肯定需要一些特殊的处理方式，说一下我的例子吧，可能不是最优的解决方案，但自我感觉良好</del><br>我遇到的需求是这样，要生成一批保证不唯一随机码（8位字母数字），然后将随机码以及其他数据构造模型列表，一并插入到数据库中；<br>需求很简单，拆解一下，就是两点<br>1、生成唯一码（字母数字）<br>2、支持大批量生成入库；<br>搞明白需求之后，就开始写代码了，首先是生成唯一码，先看代码</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">public String[] chars36 = new String[] &#123; &quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;, &quot;f&quot;, &quot;g&quot;, &quot;h&quot;, &quot;i&quot;, &quot;j&quot;, &quot;k&quot;, &quot;l&quot;, &quot;m&quot;, &quot;n&quot;, &quot;o&quot;, &quot;p&quot;, &quot;q&quot;, &quot;r&quot;, &quot;s&quot;, &quot;t&quot;, &quot;u&quot;, &quot;v&quot;, &quot;w&quot;, &quot;x&quot;, &quot;y&quot;, &quot;z&quot;, &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;, &quot;7&quot;, &quot;8&quot;, &quot;9&quot; &#125;;</span><br><span class="line"></span><br><span class="line">public String generateInviteCode()</span><br><span class="line">&#123;</span><br><span class="line">    StringBuilder shortBuffer = new StringBuilder();</span><br><span class="line">    String uuid = Guid.NewGuid().ToString(&quot;N&quot;);//生成不带&quot;-&quot;的guid串</span><br><span class="line">    for (int i = 0; i &lt; 8; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        String str = uuid.Substring(i * 4, 4);//取4位</span><br><span class="line">        int x = Convert.ToIntint32(str, 16);//将16位数字转换成10进制</span><br><span class="line">        shortBuffer.Append(chars36[x % 36]);//从上面定义好的字典串里开始拼接</span><br><span class="line">    &#125;            </span><br><span class="line">    return shortBuffer.ToString();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>代码很简单，这段代码其实是我从一位博友那参考过来的，他是用Java写的，我改成了.net的版本，代码意思注释里写的已经很明白了，我们应该知道，guid是一串由16位数字组成的长32位的字符串（有点拗口<del>）那么我们就借助guid的全球唯一性来生成这个随机码，如果觉得不够随机，可以把chars36在扩展出大写的A-Z，这样在模除运算的时候被除数就要改成62，那么这种算法构造出来的随机码出现重复的可能性是多少呢？——36的8次方，天文数字了，可以说近乎绝对不可能重复了，但为了确保万一，我们还是要在库里对应的字段加上唯一性索引。<br>对了，还要多说一点，大家看到我的generateInviteCode方法用的是String而不是string，好多博友应该都知道，string其实就是映射的String，而String是Framework下的类，也就是说，直接用String比string在代码执行效率上是要快一些的（最近对代码执行效率和简洁的追求有点疯狂</del>），但是，注意，我们还是提倡在非特殊情况下还是要用string而不是String，因为代码规范也十分重要，而且也耽误不了什么时间，就好比你买水果送亲朋送好友，总得买那些带包装的话，虽然他吃的时候也得拆，但总比你拎着一个大塑料袋苹果送人要讲究吧。<br>好了说完了第一点，再来说说第二点<br>其实关于大批量数据插入，大家应该也都有所了解，最关键的一点是要优化我们的insert语句，把多个insert合并成一个，即将多个”insert into table(a,b,c) values (1,2,3)”合并成一个，即”insert into table(a,b,c) values (1,2,3),(4,5,6),(7,8,9)”,之前看过有博友专门写了个控制台程序来测试两者差距，我在项目中也实际体验了一下（没专门写个控制台测试），对比了一下两种方式，实测，实测哦，第一方式插入10000条语句，耗时大约2分钟左右，第二种只需要6秒左右就ok了，需要注意的是，采用第二种方式的时候，values后面的条数不要太多（sqlserver的最大值是1000条）；<br>提高效率的辅助方法，就用到我上一篇提到的异步的方式了，我这里的处理方式是，将批量写入数据库的方法写成了异步，实测，插入10000条语句会在之前6秒左右的基础上提高到3秒左右，这还是包含了生成随机码的时间，可以说体验值再次大幅提升，看下代码</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">public Response MakeRandomCode(int count, int vote_id, int limit, string vote_title, string target, string remark, int activition)</span><br><span class="line">&#123;</span><br><span class="line">    Response resp = new Response() &#123; code = -2 &#125;;</span><br><span class="line">    try</span><br><span class="line">    &#123;</span><br><span class="line">        BLL.goods bllGoods = new BLL.goods();</span><br><span class="line">        int supplier_id = Convert.ToInt32(bllGoods.GetFieldValue(vote_id, &quot;sid&quot;));</span><br><span class="line">        if (string.IsNullOrEmpty(vote_title))</span><br><span class="line">            vote_title = bllGoods.GetFieldValue(vote_id, &quot;title&quot;).ToString();</span><br><span class="line">        List&lt;Model.random_code&gt; list = new List&lt;Model.random_code&gt;(count);</span><br><span class="line">        for (int i = 0; i &lt; count; i++)</span><br><span class="line">        &#123;</span><br><span class="line">            string code = generateInviteCode();                    </span><br><span class="line">            Model.random_code model = new Model.random_code()</span><br><span class="line">            &#123;</span><br><span class="line">                code = code,</span><br><span class="line">                user_id = 0,</span><br><span class="line">                supplier_id = supplier_id,</span><br><span class="line">                vote_id = vote_id,</span><br><span class="line">                add_time = DateTime.Now,</span><br><span class="line">                limit = limit,</span><br><span class="line">                update_time = null,</span><br><span class="line">                status = 0,</span><br><span class="line">                is_lock = 0,</span><br><span class="line">                vote_title = vote_title,</span><br><span class="line">                activation = activition,</span><br><span class="line">                target = target,</span><br><span class="line">                remark = remark</span><br><span class="line">            &#125;;</span><br><span class="line">            list.Add(model);//存在优化空间，list一次容量最好不要超过100000，否则.net会重新分配内存，效率大打折扣，我这里设定的最大值是50000</span><br><span class="line">        &#125;</span><br><span class="line">        BLL.random_code bllRC = new BLL.random_code();</span><br><span class="line">        int ret = bllRC.AddBulk(list);//提交</span><br><span class="line">        if (ret &gt; 0)</span><br><span class="line">        &#123;</span><br><span class="line">            resp.code = 1;</span><br><span class="line">            resp.message = &quot;创建成功&quot;;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    catch (Exception ex)</span><br><span class="line">    &#123;</span><br><span class="line">        resp.code = -1;</span><br><span class="line">        resp.message = &quot;error:&quot; + ex.Message;</span><br><span class="line">    &#125;</span><br><span class="line">    return resp;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">public int AddBulk(System.Collections.Generic.List&lt;Model.random_code&gt; list)</span><br><span class="line">&#123;</span><br><span class="line">    //return dal.AddBulk(list);</span><br><span class="line">    return System.Threading.Tasks.Task.Run(() =&gt; dal.AddBulk(list)).Result;//异步</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">public async Task&lt;int&gt; AddBulk(List&lt;Model.random_code&gt; list)</span><br><span class="line">&#123;</span><br><span class="line">    StringBuilder strSql = new StringBuilder();</span><br><span class="line">    strSql.Append(&quot;insert into  &quot; + tableName + &quot; values&quot;);    </span><br><span class="line">    int obj = 0;</span><br><span class="line">    int cnt = 0;</span><br><span class="line">    foreach (var item in list)</span><br><span class="line">    &#123;</span><br><span class="line">        cnt++;</span><br><span class="line">        strSql.Append(&quot;(&apos;&quot; + item.code + &quot;&apos;,&quot; + item.user_id + &quot;,&quot; + item.supplier_id + &quot;,&quot; + item.vote_id + &quot;,&apos;&quot; + item.vote_title + &quot;&apos;,&apos;&quot; + item.add_time.ToString(&quot;yyyy-MM-dd HH:mm:ss&quot;) + &quot;&apos;,&quot; + item.limit + &quot;,null,&quot; + item.status + &quot;,&quot; + item.is_lock + &quot;,&apos;&quot; + item.remark + &quot;&apos;,&quot; + item.activation + &quot;,&apos;&quot; + item.target + &quot;&apos;)&quot;);</span><br><span class="line">        strSql.Append(&quot;,&quot;);</span><br><span class="line">        if (cnt % 100 == 0)//每100条提交一次</span><br><span class="line">        &#123;</span><br><span class="line">            obj = DbHelperSQL.ExecuteSql(strSql.ToString().Trim(&apos;,&apos;));</span><br><span class="line">            strSql.Clear();</span><br><span class="line">            if (list.Count &gt; cnt)</span><br><span class="line">                strSql.Append(&quot;insert into  &quot; + tableName + &quot; values&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    if (cnt == list.Count &amp;&amp; cnt % 100 &gt; 0)</span><br><span class="line">    &#123;</span><br><span class="line">        obj = DbHelperSQL.ExecuteSql(strSql.ToString().Trim(&apos;,&apos;));</span><br><span class="line">    &#125;    </span><br><span class="line">    await Task.Delay(100);</span><br><span class="line">    return obj;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>第三段代码直接拼的sql字符串，因为我的数据验证放到了模型里，所以保证进到数据逻辑层的代码肯定都是符合数据规范的，不会出现sql注入的问题。<br>说到这，不得不提一嘴orm框架了（比如很熟悉的ef），用orm很大的一个好处就是，当我们写lambda表达式进行大批量插入操作的时候，ef底层就会自动帮我们拼接成”insert into table(a,b,c) values (1,2,3),(4,5,6),(7,8,9)”这种格式，所以，用orm，在执行效率上不会出现什么问题，实际允许的情况下，推荐orm框架，写法简单，更方便。<br>好了，大概就是这样了，对了我文中所提到的测试结果，都是在测试服务期上进行的，阿里云的入门级服务器（2G内存，单核2.8GHzCPU，普通硬盘），如果在正式服务器，这个相应时间还会再有所提高，专业开发人员看了这么快的执行结果，甚至会让你产生系统出错了美好错觉，而非开发人员的体验就非常棒了！<br>附上几张张效果图<br><img src="1.png" alt="1"><br><img src="2.png" alt="2"><br><img src="3.png" alt="3"><br>对了，再说一个跟本文无关的消息，算是个彩蛋吧，应该好多博友也都知道了，就是win10和对应的server，在最新的更新版本里，居然原生支持ssh了！兴奋的昨天赶紧试了下，还是很不赖的，用powershell就可以打开任何Linux发行版系统的命令行了，而且还可以打开windows的，以后说不定powershell也会借此东风火一把<br><img src="%E5%BD%A9%E8%9B%8B1.png" alt="彩蛋1"><br><img src="%E5%BD%A9%E8%9B%8B2.png" alt="彩蛋2"></p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/hexo/tags/开发笔记/" rel="tag"># 开发笔记</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/hexo/2018/12/18/先用起来再细研究——游标（一）/" rel="next" title="先用起来再细研究——游标（一）">
                <i class="fa fa-chevron-left"></i> 先用起来再细研究——游标（一）
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/hexo/2019/01/02/听罗振宇跨年演讲？你们的时间真多/" rel="prev" title="听罗振宇跨年演讲？你们的时间真多">
                听罗振宇跨年演讲？你们的时间真多 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
        <!-- Go to www.addthis.com/dashboard to customize your tools -->
<div class="addthis_inline_share_toolbox">
  <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5bbb2338b87602f0" async="async"></script>
</div>

      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="lv-container" data-id="city" data-uid="MTAyMC8zOTA1My8xNTU4MA"></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">Tony</p>
              <p class="site-description motion-element" itemprop="description">学习总结</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/hexo/archives/">
              
                  <span class="site-state-item-count">58</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/hexo/tags/index.html">
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">tags</span>
                </a>
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Tony</span>

  
</div>


  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a></div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">Theme &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Muse</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/hexo/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/hexo/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/hexo/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/hexo/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/hexo/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/hexo/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/hexo/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  












  





  

  

  

  
  

  

  

  

</body>
</html>
